<template>
  <div class="popup-container">
    <!-- 阻止冒泡 -->
    <div @click.stop="open">
      <slot></slot>
    </div>

    <!--弹窗，可用于对话框、弹出式菜单等-->
    <!--弹出式菜单-->
    <div class="popup" v-show="isShow" ref="popup">
      <div class="popup-header">
        <span class="popup-title">{{ title }}</span>
        <a class="popup-header-close" @click="close" ref="closeIcon"
          ><i class="icon icon-close"></i
        ></a>
      </div>

      <div class="popup-content">
        <slot name="content"></slot>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "PopUp",

  props: {
    title: {
      type: String,
      default: "菜单",
    },
  },

  data() {
    return {
      isShow: false,
    };
  },

  methods: {
    open() {
      this.isShow = true;

      let $popup = this.$refs.popup;

      $popup.style.left = "0px";

      //  打开弹窗后, 给window加上点击弹窗外部时，关闭弹窗的事件
      //  但是要注意，弹窗的click事件会冒泡到window
      //  所以触发弹窗打开的时候，也会触发window的关闭
      window.addEventListener("click", this.close);

      //  但状态改变时，视图并不是立即改变，所以我们要将回调延迟到下次 DOM 更新循环之后执行
      this.$nextTick(() => {
        let rect = $popup.getBoundingClientRect();

        let left = 0;

        //  超过屏幕右边边界
        if (rect.right > window.innerWidth) {
          left = -rect.width + this.$el.offsetWidth;
        }
        $popup.style.left = left + "px";
        // console.log($popup.getBoundingClientRect(), window.innerWidth);
      });

      this.$emit("open");
    },

    close(e) {
      //  情况一: 其他组件通过ref直接调用close方法来关闭，这时候e是不存在的
      //  情况二: 点击的时候位于弹窗外, 检测冒泡路径是否有popup
      //  情况三: 点击关闭icon, 检测冒泡路径是否有icon
      if (
        !e ||
        !e.path.includes(this.$refs.popup) ||
        e.path.includes(this.$refs.closeIcon)
      ) {
        this.isShow = false;
        window.removeEventListener("click", this.close);
        this.$emit("close");
      }
    },
  },
};
</script>

<style>
</style>